--love 1

require("util")

-- map encoding
local function round(v) return math.floor(v+0.5) end
local function encodeMap(heightImgdata, colorImgdata)
	local data = {}
	local w, h = heightImgdata:getWidth(), heightImgdata:getHeight()
	if colorImgdata:getWidth()~=w or colorImgdata:getHeight()~=h then
		print("color and height maps are different sizes")
		return nil
	end
	--assert(w%map.chunkSize==0 and h%map.chunkSize==0, "map dimensions are not divisible by chunk size")
	for y = 0, h-1 do
		for x = 0, w-1 do
			local h = heightImgdata:getPixel(x, y)
			local r, g, b = colorImgdata:getPixel(x, y)
			h = round(h*255)
			r = round(r*255)
			g = round(g*255)
			b = round(b*255)
			local pStr = encodeBase64(r*256^3 + g*256^2 + b*256 + h, 6)
			table.insert(data, pStr)
		end
	end
	return table.concat(data)
end
local function exportMap(fn, heightImgdata, colorImgdata)
	print("Exporting as "..fn)
	local txt = encodeMap(heightImgdata, colorImgdata)
	if not txt then return end
	local fo = io.open(fn, "wb")
	fo:write(txt)
	fo:close()
end
-- exporting
local heightmapImgdata, heightmapImg, colormapImgdata, colormapImg
local exportFilename
local function exportCurrentMap()
	assert(heightmapImgdata and colormapImgdata and exportFilename, "exportCurrentMap - Tried to export map before proper import")
	exportMap(exportFilename, heightmapImgdata, colormapImgdata)
end
-- importing
local li = love.image
local lf = love.filesystem
local lg = love.graphics
local importColorMap = false
local function getExportFilename(fn)
	assert(fn:find("%.png$"), "getExportFilename - filename is not .png")
	return fn:gsub("%.png$", ".map")
end
local function importImgData(imgdata, fn)
	if not importColorMap then -- heightmap
		heightmapImgdata = imgdata
		heightmapImg = lg.newImage(imgdata)
		exportFilename = getExportFilename(fn)
		importColorMap = true
	else                       -- colormap
		colormapImgdata = imgdata
		colormapImg = lg.newImage(imgdata)
		importColorMap = false
	end
end
local function importFile(file)
	local fn = file:getFilename()
	file:open("r")
	local txt = file:read()
	file:close()
	local filedata = lf.newFileData(txt, "image.png")
	local imgdata = li.newImageData(filedata)
	importImgData(imgdata, fn)
end
-- graphics
local function drawFit(img, x, y, w, h)
	local iw, ih = img:getWidth(), img:getHeight()
	local sx, sy = w/iw, h/ih
	local scale = math.min(sx, sy)
	lg.draw(img, x, y, 0, scale, scale)
end
local function isInRect(x, y, r)
	return x>r[1] and x<r[1]+r[3] and y>r[2] and y<r[2]+r[4]
end
-- user interface
local le = love.event
function love.load()
	lg.setDefaultFilter("nearest", "nearest")
	local font = lg.newFont(16)
	lg.setFont(font)
end
function love.filedropped(file)
	local fn = file:getFilename()
	if fn:find("%.png$") then
		importFile(file)
	else
		print("File is not png: "..fn)
	end
end
function love.keypressed(k)
	if k=="escape" then le.quit()
	end
end
local mapDrawY = 20
local mapDrawBorder = 10
local mapDrawSize = {380, 380}
local heightmapRect = { mapDrawBorder                   , mapDrawBorder+mapDrawY, mapDrawSize[1]-mapDrawBorder, mapDrawSize[2]-mapDrawBorder }
local colormapRect  = { mapDrawSize[1] + mapDrawBorder*2, mapDrawBorder+mapDrawY, mapDrawSize[1]-mapDrawBorder, mapDrawSize[2]-mapDrawBorder }
local buttons = {
	export = {
		text = "Export",
		rect = {10, 500, 200, 30},
		func = function() print("Exporting map") exportCurrentMap() end,
	},
}
local lm = love.mouse
function love.draw()
	lg.setLineWidth(2)
	lg.setColor(1,1,1)
	-- maps
	if heightmapImg then drawFit(heightmapImg, unpack(heightmapRect)) end
	if colormapImg  then drawFit(colormapImg , unpack(colormapRect )) end
	if not importColorMap then lg.rectangle("line", unpack(heightmapRect))
	else                       lg.rectangle("line", unpack(colormapRect )) end
	lg.print("Height Map"..((not importColorMap) and " (Drag to import)" or ""),  10, 10)
	lg.print("Color Map" ..((    importColorMap) and " (Drag to import)" or ""), 410, 10)
	-- info
	local ix, iy, i2x = 10, 420, 410
	if heightmapImgdata then lg.print("Size: "..heightmapImgdata:getWidth().."x"..heightmapImgdata:getHeight(), ix , iy) end
	if colormapImgdata  then lg.print("Size: "..colormapImgdata :getWidth().."x"..colormapImgdata :getHeight(), i2x, iy) end
	if heightmapImgdata and colormapImgdata and (heightmapImgdata:getWidth() ~= colormapImgdata:getWidth() or heightmapImgdata:getHeight() ~= colormapImgdata:getHeight()) then
		lg.print("Error - Sizes are different!", i2x+150, iy)
		buttons.export.text = "Export (Sizes different)"
		buttons.export.gray = true
	elseif not heightmapImgdata then
		buttons.export.text = "Export (No heightmap)"
		buttons.export.gray = true
	elseif not colormapImgdata then
		buttons.export.text = "Export (No colormap)"
		buttons.export.gray = true
	else
		buttons.export.text = "Export"
		buttons.export.gray = false
	end
	if exportFilename then lg.printf("Export filename: \""..exportFilename.."\"", ix, iy+20, 780, "left") end
	-- buttons
	local mx, my, m1 = lm.getX(), lm.getY(), lm.isDown(1)
	for _, b in pairs(buttons) do
		if b.gray then lg.setColor(0.7,0.7,0.7) else lg.setColor(1,1,1) end
		local hover = isInRect(mx, my, b.rect)
		local press = hover and m1 and (not b.gray)
		lg.setLineWidth(hover and (press and 6 or 4) or 2)
		lg.rectangle("line", unpack(b.rect))
		lg.printf(b.text, b.rect[1]+5, b.rect[2]+5, b.rect[3], "center")
		if press then
			if not b.press then
				b.press = true
				b.func()
			end
		else
			b.press = false
		end
	end
end
